﻿/* EntitiesToDTOs. Copyright (c) 2011. Fabian Fernandez.
 * http://entitiestodtos.codeplex.com
 * Licensed by Common Development and Distribution License (CDDL).
 * http://entitiestodtos.codeplex.com/license
 * Fabian Fernandez. 
 * http://www.linkedin.com/in/fabianfernandezb/en
 * */
using Microsoft.VisualStudio.Shell;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using EntitiesToDTOs.Properties;

namespace EntitiesToDTOs.Helpers
{
    /// <summary>
    /// Manages the Log operations.
    /// </summary>
    internal class LogManager
    {
        /// <summary>
        /// Indicates if the Log process is active.
        /// </summary>
        public static bool IsLogActive
        {
            get
            {
                return _isLogActive;
            }
            set
            {
                _isLogActive = value;
            }
        }
        private static bool _isLogActive = false;
        

        /// <summary>
        /// Logs an Exception.
        /// </summary>
        /// <param name="ex">Exception to log.</param>
        public static void LogError(Exception ex)
        {
            if (LogManager.IsLogActive)
            {
                LogManager.Log(string.Format(Resources.LogError,
                    DateTime.Now.ToShortDateString(), DateTime.Now.ToLongTimeString()) + Environment.NewLine +
                    ex.Message + Environment.NewLine + ex.StackTrace);
            }
        }

        /// <summary>
        /// Logs an Info message
        /// </summary>
        /// <param name="logMessage"></param>
        public static void LogInfo(string logMessage)
        {
            if (LogManager.IsLogActive)
            {
                LogManager.Log(string.Format(Resources.LogInfo,
                    DateTime.Now.ToShortDateString(), DateTime.Now.ToLongTimeString()) + Environment.NewLine +
                    logMessage);
            }
        }

        /// <summary>
        /// Logs method start.
        /// </summary>
        public static void LogMethodStart()
        {
            if (LogManager.IsLogActive)
            {
                // Get call stack
                StackTrace stackTrace = new StackTrace();

                // Get calling method name
                string methodName = stackTrace.GetFrame(1).GetMethod().Name;

                LogManager.LogInfo(string.Format(Resources.Info_MethodStart, methodName));
            }
        }

        /// <summary>
        /// Logs method end.
        /// </summary>
        public static void LogMethodEnd()
        {
            if (LogManager.IsLogActive)
            {
                // Get call stack
                StackTrace stackTrace = new StackTrace();

                // Get calling method name
                string methodName = stackTrace.GetFrame(1).GetMethod().Name;

                LogManager.LogInfo(string.Format(Resources.Info_MethodEnd, methodName));
            }
        }

        /// <summary>
        /// Logs a message
        /// </summary>
        /// <param name="logMessage"></param>
        private static void Log(string logMessage)
        {
            var worker = new BackgroundWorker();
            worker.WorkerReportsProgress = false;

            worker.DoWork += new DoWorkEventHandler(LogManager.Log_DoWork);

            worker.RunWorkerAsync(logMessage);
        }

        /// <summary>
        /// Executed when the BackgroundWorker decides to execute the provided Logic (i.e., the Log process).
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        static void Log_DoWork(object sender, DoWorkEventArgs args)
        {
            try
            {
                var logMessage = (string)args.Argument;

                // Append message to Log file
                File.AppendAllText(Resources.LogFilePath, logMessage +
                    Environment.NewLine + Resources.LogSeparator + Environment.NewLine);
            }
            catch (Exception ex)
            {
                // Create a Warning if Log is not possible
                string message = (args.Argument != null ? args.Argument.ToString() : string.Empty);

                message = string.Format(Resources.Warning_CouldNotLogMessage, message) + Environment.NewLine + 
                    string.Format(Resources.Warning_ExceptionWhenLog, ex.Message);

                // Add warning to ErrorList pane
                VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, message, null, null, null, null);
            }
        }
    }
}